package org.putrpctorest.resource.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.putrpctorest.resource.Method;
import org.putrpctorest.resource.Verb;

public class MethodImpl implements Method {
	
	private String description;
	private Verb verb;
	private Set<String> produces = new HashSet<String>();
	private Set<String> consumes = new HashSet<String>();
	private List<ParameterImpl> parameters = new ArrayList<ParameterImpl>();
	private Class<?> returnEntity;
	private ResourceImpl resource;
	
	@Override
	public String getId() {
		return getResource().getPath() + "." + getVerb().name();
	}
	
	public void setVerb(Verb verb) {
		this.verb = verb;
	}
	
	@Override
	public Verb getVerb() {
		return verb;
	}
	
	public void setProduces(Set<String> mediaTypes) {
		produces = new HashSet<String>(mediaTypes);
	}
	
	@Override
	public Set<String> getProduces() {
		Set<String> allProduces = new HashSet<String>();
		allProduces.addAll(produces);
		allProduces.addAll(getResource().getProduces());
		return Collections.unmodifiableSet(allProduces);
	}
	
	public void addProduces(String mediaType) {
		produces.add(mediaType);
	}
	
	public void setConsumes(Set<String> mediaTypes) {
		consumes = new HashSet<String>(mediaTypes);
	}
	
	@Override
	public Set<String> getConsumes() {
		Set<String> allConsumes = new HashSet<String>();
		allConsumes.addAll(consumes);
		allConsumes.addAll(getResource().getConsumes());
		return Collections.unmodifiableSet(allConsumes);
	}
	
	public  void addConsumes(String mediaType) {
		consumes.add(mediaType);
	}
	
	public void setParameters(List<ParameterImpl> parameters) {
		this.parameters = new ArrayList<ParameterImpl>(parameters);
	}
	
	public List<ParameterImpl> getParameters() {
		return Collections.unmodifiableList(parameters);
	}
	
	@Override
	public ParameterImpl getParameter(String name) {
		for(ParameterImpl parameter:getParameters()) {
			if (parameter.getName().equals(name)) {
				return parameter;
			}
		}
		return null;
	}
	
	public void addParameter(ParameterImpl parameter) {
		parameters.add(parameter);
	}

    public Class<?> getReturnEntity() {
        return returnEntity;
    }
    
    public void setReturnEntity(Class<?> returnEntity) {
        this.returnEntity = returnEntity;
    }

	@Override
	public ResourceImpl getResource() {
		return resource;
	}

	public void setResource(ResourceImpl resource) {
		 this.resource = resource;
		 if (resource.getMethod(getVerb()) == null) {
 		   resource.addMethod(this);
		 }
	}

    @Override
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description=description;
    }
 
}
